package main

import (
	"fmt"
	"os"
	"sort"
	"text/tabwriter"
	"time"
)

type Track struct {
	Title  string
	Artist string
	Album  string
	Year   int
	Length time.Duration
}

func length(str string) time.Duration {
	duration, err := time.ParseDuration(str)
	if err != nil {
		panic(err)
	}
	return duration
}

// 自定义新类型，来实现自定义排序
type sortTrackByArtist []*Track

func (s sortTrackByArtist) Len() int {
	return len(s)
}

func (s sortTrackByArtist) Less(i, j int) bool {
	return s[i].Artist < s[j].Artist
}

func (s sortTrackByArtist) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

// CustomSort 结构体实现排序接口
type CustomSort struct {
	t    []*Track
	less func(x, y *Track) bool
}

func (c CustomSort) Len() int {
	return len(c.t)
}

func (c CustomSort) Less(i, j int) bool {
	return c.less(c.t[i], c.t[j])
}

func (c CustomSort) Swap(i, j int) {
	c.t[i], c.t[j] = c.t[j], c.t[i]
}

func main() {
	var track = []*Track{
		{"Go", "Delilan 24", "Roots up", 2022, length("3m38s")},
		{"Go1", "Delilan 222", "Roots up1", 2012, length("3m38s")},
		{"Go2", "Delilan ss", "Roots up2", 2032, length("4m38s")},
		{"Go3", "Delilan root", "Roots up3", 2002, length("5m38s")},
	}

	sort.Sort(sortTrackByArtist(track))

	// 使用结构进行自定义排序，可以进行多组条件排序
	sort.Sort(CustomSort{track, func(x, y *Track) bool {
		// 条件1
		if x.Artist != y.Artist {
			return x.Artist < y.Artist
		}
		// 条件2
		// ...

		return false
	}})

	const format = "%v\t%v\t%v\t%v\t%v\t\n"

	tw := new(tabwriter.Writer).Init(os.Stdout, 0, 8, 2, ' ', 0)
	fmt.Fprintf(tw, format, "Title", "Artist", "Album", "Year", "Length")
	fmt.Fprintf(tw, format, "-----", "-----", "-----", "-----", "-----")
	for _, t := range track {
		fmt.Fprintf(tw, format, t.Title, t.Artist, t.Album, t.Year, t.Length)
	}
	tw.Flush()

}
